#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "GameState.h"
#include "Hero.h"
#include <memory>
#include <vector>


#define BG "/Users/yzy/Desktop/cpp/sdl2-learning-record/cpp_sdl2_plane/asset/bg.jpeg"

class PlaneGame {
private:
    SDL_Window* m_window;
    SDL_Renderer* m_renderer;
 
    GameState m_state;

    SDL_Texture* m_backgroundTexture;
    SDL_Surface* m_backgroundSurface;
    char* m_imagefile;

    std::vector<Sprite*> childs;

public:
    PlaneGame() : m_state(START), 
        m_window(nullptr),
        m_renderer(nullptr), 
        m_backgroundTexture(nullptr), 
        m_backgroundSurface(nullptr),
        m_imagefile(nullptr) {
  
        IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
        
    }

    ~PlaneGame() {
      
        if (m_renderer != nullptr) {
            SDL_DestroyRenderer(m_renderer);
        }
        if (m_window != nullptr) {
            SDL_DestroyWindow(m_window);
        }
        if (m_backgroundTexture != nullptr) {
            SDL_DestroyTexture(m_backgroundTexture);
        }
        if (m_backgroundSurface != nullptr) {
            SDL_FreeSurface(m_backgroundSurface);
        }
        SDL_Quit();
    }

    /**
     * @brief 为啥想实现多态的，必须使用指针或者引用，不能用对象 ？？？
     * 因为  如子类对象之间的复制，虚函数指针会进行正常复制，
     * 但是如果将一个子类对象赋值给一个父类对象，
     * 编译器保证该父类对象的虚函数还是指向父类的虚函数表，不会指向子类对象的虚函数表。
     * @param sprite 
     */
    // void addChild(Sprite sprite){
    //     sprite.m_renderer = this->m_renderer;
    //     childs.push_back(sprite);
    // }
    void addChild(Sprite* sprite){
        sprite->setRenderer(m_renderer);
        sprite->init();
        childs.push_back(sprite);
    }

    SDL_Renderer* getRenderer(){
        return this->m_renderer;
    }

    void loadPNG() {
       m_backgroundSurface = IMG_LoadPNG_RW(SDL_RWFromFile(BG, "rb"));
        if (!m_backgroundSurface) {
          
            exit(-5);
        }
        m_backgroundTexture = SDL_CreateTextureFromSurface(m_renderer, m_backgroundSurface);
    
        SDL_FreeSurface(m_backgroundSurface);
        m_backgroundSurface = NULL;

        SDL_RenderSetScale(m_renderer, 1.5, 1.5);
    }

    void init() {
        if (SDL_Init(SDL_INIT_VIDEO)) {
            SDL_Log("init error : %s", SDL_GetError());
           
            exit(-1);
        }
        m_backgroundSurface = IMG_LoadPNG_RW(SDL_RWFromFile(BG, "rb"));
        // m_w = m_backgroundSurface->w * 1.5;
        // m_h = m_backgroundSurface->h * 1.5;

        m_window = SDL_CreateWindow("NBA",
            SDL_WINDOWPOS_CENTERED,
            SDL_WINDOWPOS_CENTERED,
            m_backgroundSurface->w * 1.5, m_backgroundSurface->h * 0.5,
            SDL_WINDOW_SHOWN
        );

        if (m_window == NULL) {
            SDL_Log("create window error %s", SDL_GetError());
            exit(-1);
        }
        m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED);
        if (m_renderer == NULL) {
            SDL_Log("create render error %s", SDL_GetError());
        }

        this->loadPNG();
    }

     void mainLoop() {
        while (true)
        {
            render();
            SDL_Event event;
            while (SDL_PollEvent(&event)) {
                // printf("event is %#x\n", event.type); // test code
                switch (event.type)
                {
                case SDL_MOUSEMOTION:
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    break;
                case SDL_MOUSEBUTTONUP:
                   for (int i = 0; i < childs.size(); i++){
                       childs[i]->onMouse();
                    }
                    break;
                case SDL_QUIT:
                    return;

                default:
                    break;
                }
                if (SDL_QUIT == event.type) {
                    return;
                }
            }
        }
    }

    void render() {
        SDL_SetRenderDrawColor(m_renderer, 0xFF, 0xFF, 0xFF, 0xFF);
        SDL_RenderClear(m_renderer);

        SDL_RenderCopy(m_renderer, m_backgroundTexture, NULL, NULL);

        for (int i = 0; i < childs.size(); i++){
            childs[i]->render();
        }
        SDL_RenderPresent(m_renderer);
        SDL_Delay(90);
        //SDL_UpdateWindowSurface(m_window);
    }

};